import axios, {
  AxiosError,
  type AxiosProgressEvent,
  type AxiosRequestConfig,
  type AxiosResponse,
} from 'axios'
import { getToken } from '../stores/loginStore'
import { log } from './com'
import myRouter from '@/router'
import type { CallResult } from '@/components/baseBean'
import { hideLoading } from '@/components/components/loadingdialog/my-loading-dialog'
import { toast } from '@/components/components/toast/my-toast'
const baseUrl = import.meta.env.VITE_API_BASE_URL
export const logShow: boolean = import.meta.env.VITE_LOG == '1'
const logHttpShow: boolean = import.meta.env.VITE_LOG_HTTP == '1'

export function getQueryVariable(variable: string) {
  const query = window.location.search.substring(1)
  const vars = query.split('&')
  for (let i = 0; i < vars.length; i++) {
    const pair = vars[i].split('=')
    if (pair[0] == variable) {
      return pair[1]
    }
  }
  return ''
}
export function isEmpty(obj: number | string | object | null | undefined | []) {
  return (
    obj == null ||
    obj == undefined ||
    obj.toString().length <= 0 ||
    0 == obj ||
    (obj && (obj as []).length == 0)
  )
}
export function isApiOk<T>(resp: CallResult<T>) {
  return resp && resp.code == 200
}
export function isApiOkAndNotEmpty<T>(resp: CallResult<T>) {
  return resp && resp.code == 200 && resp.data
}

export class MyService {
  // 基础配置
  private static axiosInstance = axios.create({
    baseURL: baseUrl, // 替换为你的 API 基础 URL
    timeout: 30000, // 请求超时时间
    headers: {
      'Content-Type': 'application/json',
    },
  })
  private static addInterceptors() {
    // 添加请求拦截器（在 axiosInstance 创建后添加）
    this.axiosInstance.interceptors.request.use(
      (config) => {
        // 在发送请求前做些什么（如添加 token）
        const token = getToken()
        if (token) {
          config.headers.token = `${token}`
        }
        return config
      },
      (error) => {
        // 对请求错误做些什么
        hideLoading()
        return Promise.reject(error)
      },
    )
    // 添加响应拦截器
    this.axiosInstance.interceptors.response.use(
      (response) => {
        // 对响应数据做些什么
        hideLoading()
        return response
      },
      (error) => {
        // 对响应错误做些什么（如统一处理 401 错误）
        hideLoading()
        return Promise.reject(error)
      },
    )
  }
  /**
   * ----------------------GET----------------------------------
   */
  static async apiGet<T>(url: string, config?: unknown): Promise<CallResult<T>> {
    let result: CallResult<T> = {
      code: 0,
      message: '',
    }
    try {
      this.addInterceptors()
      const response: AxiosResponse<CallResult<T>> = await this.axiosInstance.get(url, {
        data: config,
      })
      // 成功响应处理
      result.code = response.data.code
      result.message = response.data.message
      result.data = response.data.data
      toast(result.message)
    } catch (error: unknown) {
      // 类型守卫：检查是否为 Axios 错误
      result = this.onErrorAction(error)
    }
    if (logHttpShow) {
      log('【请求路径】' + baseUrl + url)
      log('【请求结果】', result)
    }
    return result
  }
  /**
   * ----------------------------POST----------------------------
   */
  static async apiPost<T>(
    url: string,
    data?: object,
    config?: AxiosRequestConfig,
  ): Promise<CallResult<T>> {
    let result: CallResult<T> = {
      code: 0,
      message: '',
    }
    try {
      this.addInterceptors()
      // 转换响应式数据为普通对象
      const response: AxiosResponse<CallResult<T>> = await this.axiosInstance.post(
        url,
        data,
        config,
      )
      // 成功响应处理
      result.code = response.data.code
      result.message = response.data.message
      result.data = response.data.data
    } catch (error: unknown) {
      // 异常处理
      result = this.onErrorAction(error)
    }
    if (logHttpShow) {
      log('【请求路径】' + baseUrl + url)
      log('【请求结果】', result)
    }
    return result
  }
  /**
   * -----------------------------文件上传方法--------------------------
   */
  static async uploadFile<T>(
    url: string,
    formData: FormData,
    onProgress?: (progress: number) => void, // 进度回调
  ): Promise<CallResult<T>> {
    let result: CallResult<T> = {
      code: 0,
      message: '',
    }
    try {
      this.addInterceptors()
      // 创建FormData并添加文件和参数
      // const formData = new FormData()
      // formData.append('file', file)
      // 配置请求头为multipart/form-data
      const config: AxiosRequestConfig = {
        headers: {
          'Content-Type': 'multipart/form-data',
        },
        // 监听上传进度
        onUploadProgress: (event: AxiosProgressEvent) => {
          const progress = Math.round((event.loaded / event.total!) * 100)
          if (onProgress) {
            onProgress(progress)
          }
        },
      }

      // 发送POST请求
      const response: AxiosResponse<CallResult<T>> = await this.axiosInstance.post(
        url,
        formData,
        config,
      )
      // 处理响应
      result.code = response.data.code
      result.message = response.data.message
      result.data = response.data.data
    } catch (error: unknown) {
      result = this.onErrorAction(error)
    }
    if (logHttpShow) {
      log('【上传路径】' + baseUrl + url)
      log('【上传结果】', result)
    }
    return result
  }
  /**
   * 验证URL是否有效（可访问）------不可用
   * @param url 待验证的URL
   * @param timeout 超时时间（毫秒）
   * @returns Promise<boolean> 表示URL是否有效
   */
  static async checkUrl(url: string, timeout = 5000): Promise<boolean> {
    if (!url) return false

    try {
      // 使用HEAD方法，只获取响应头，不下载整个文件
      const controller = new AbortController()
      const signal = controller.signal

      // 设置超时
      const timeoutId = setTimeout(() => {
        controller.abort()
      }, timeout)

      const response = await fetch(url, {
        method: 'POST',
        signal,
      })

      // 清除超时计时器
      clearTimeout(timeoutId)

      // 检查状态码（200-299表示成功）
      return response.ok
    } catch (error) {
      console.error('URL验证失败:', error)
      return false
    }
  }

  private static onErrorAction<T>(error: unknown): CallResult<T> {
    // const result = new CallResult<T>()
    const result: CallResult<T> = {
      code: 0,
      message: '',
    }
    try {
      // 类型守卫：检查是否为 Axios 错误
      if (axios.isAxiosError(error)) {
        const axiosError: AxiosError = error
        if (axiosError.response && axiosError.response.data) {
          const r1 = axiosError.response.data as unknown as CallResult<void>
          result.code = r1.code
          if (r1 && !isEmpty(r1.message)) {
            result.message = r1.message
          } else {
            result.message = '无法获得请求结果'
          }
          if (result.code == 401) {
            log(result.message)
            myRouter.push('/login')
          }
        } else {
          result.code = 2001
          result.message = '服务器无响应'
        }
      } else {
        // 非 Axios 错误
        result.code = 4500
        result.message = (error as Error).message || '未知错误'
      }
    } catch {
      result.code = 9100
      result.message = (error as Error).message || '运行时异常'
    }
    toast(result.message)
    return result
  }
}
